using System;
using System.Collections;
using System.Configuration;
using System.Data;
using System.IO;
using System.Linq;
using System.Reflection;
using System.Web;
using System.Web.Security;
using System.Web.SessionState;
using System.Xml.Linq;
using Edge.Business.Domain.Application;
using Edge.Business.Domain.Filters;
using Edge.Business.Entities;
using Edge.Business.Managers;
using Edge.Business.Security;
using Edge.Common.ComponentModel;
using Edge.Common.ComponentModel.Exceptions;
using Edge.Common.ComponentModel.Notification;
using Edge.Common.ControlFlow;
using Edge.Common.Mail;
using Edge.Common.Mail.Impl;
using Edge.Common.Services;
using Edge.Common.TextTemplates.Impl.ASPNET;
using Edge.Common.Web;
using Edge.Common.Web.Application;
using Edge.Common.Web.Naming;
using Edge.Common.Web.Navigation;
using Edge.Common.Web.Notification;
using Edge.DAL.Common.SessionManagment;
using Edge.DAL.Managers;
using Edge.WebCode;
using log4net;
using log4net.Config;
using log4net.Util;
using Shop.Business.Domain.Customers;
using Shop.DAL;
using NHibernate;

namespace Shop.Web
{
    public class Global : HttpApplication
    {

        void Application_Start(object sender, EventArgs e)
        {
            try
            {
                //DOMConfigurator.Configure();

                // setup DAL
                ShopInitializer.Setup(true);

                // TODO use IoC container Spring.NET or CastleProject IoC

                InitilizeLog4net();

                string appBase = SystemInfo.ApplicationBaseDirectory;

               Locator.AddService<ISessionProvider>(new WebSessionProvider());

               Locator.AddService<INavigationService>(new SimpleNavigationService());


                #region Mail configuration

                SendMailService mailService = new SendMailService();
                SendMailServiceConfigurator mailConfigurator = new SendMailServiceConfigurator(mailService);
                mailConfigurator.Configure();
                Locator.AddService<ISendMailService>(mailService);

                #endregion

                #region Setup text templates

//                TextEngineFactory.Instance().Referensec.AddRange(
//                    new Assembly[]
//                        {
//                            typeof(Assert).Assembly, 
//                            typeof(Iesi.Collections.ISet).Assembly, 
//                            typeof(INavigationService).Assembly,
//                            typeof(ILog).Assembly
//            });
//

                #endregion

                #region Filters

                SimpleFiltersManager simpleFiltersManager = new SimpleFiltersManager();
                Locator.AddService<IFiltersManager>(simpleFiltersManager);

                #endregion

                Locator.AddService<INotificationManager>(new NotificationManager());

                Locator.AddService<IEntityDescriptionsService>(new EntityDescriptionsService());

                //Locator.AddService<ISearchesRepository>(new SearchesRepository());

                //Locator.AddService<ISecurityService>(new SecurityService());

                Locator.AddService<IContextObjects>(new ContextObjects());
//
                Locator.AddService<IPersonManager<Customer>>(new PersonManager<Customer, CustomerHolder, ICustomerManager>());

            }
            catch (Exception ex)
            {
                Log.Fatal(ex);
                RegisterError(ex);
            }

            Log.Info("Application Started");
        }

         #region Constants

        private const string NOT_AVALIABLE_PAGE = "NotAvailable.aspx";

        #endregion

        #region Fields

        private static bool initialized = true;

        private static string startupException = null;

        private readonly static ILog log = LogManager.GetLogger(MethodInfo.GetCurrentMethod().DeclaringType);

        #endregion

        #region Constructor

        public Global()
        {
        }

        #endregion

        #region Properties

        public bool Initialized
        {
            get { return initialized; }
        }

        public string StartupException
        {
            get { return startupException; }
        }

        public static ILog Log
        {
            get { return log; }
        }

        #endregion


        protected void RegisterError(Exception ex)
        {
            startupException = ex.ToString() +
                               "\n" + ex.Message +
                               "\n" + ex.Source +
                               "\n" + ex.StackTrace;
            initialized = false;
        }

        protected void CheckInitialized()
        {
            if (!Initialized)
            {
                HttpRequest request = HttpContext.Current.Request;
                string naPath = request.ApplicationPath + "/" + NOT_AVALIABLE_PAGE;
                naPath = naPath.Replace("//", "/");
                if (naPath != request.Path)
                    HttpContext.Current.Response.Redirect(NOT_AVALIABLE_PAGE, true);
            }
        }

        public void InitilizeLog4net()
        {
            const string FILE_NAME = "log4net.config";
            string configFile = SystemInfo.ApplicationBaseDirectory + FILE_NAME;
            XmlConfigurator.ConfigureAndWatch(new FileInfo(configFile));
        }
        void Application_BeginRequest(Object sender, EventArgs e)
        {
            HttpApplication app = (HttpApplication)sender;

            CheckBaseAndCurrentUrl checkBaseAndCurrentUrl = new CheckBaseAndCurrentUrl();
            string urlRedirect;
            if (checkBaseAndCurrentUrl.NeedRedirect(out urlRedirect))
                app.Response.Redirect(urlRedirect, true);

            CheckInitialized();
        }

        void Application_End(object sender, EventArgs e)
        {
            //  Code that runs on application shutdown
        }

        void Application_Error(object sender, EventArgs e)
        {
            Exception ex = Server.GetLastError().GetBaseException();

            if (ex is WebParameterException || ex is ObjectNotFoundException)
            {
//#if !DEBUG
				HttpContext.Current.Response.Clear();
				HttpContext.Current.Response.StatusCode = 400;
				HttpContext.Current.Response.StatusDescription = "HTTP/1.0 400 Bad Request";
				HttpContext.Current.Response.End();
//#endif
            }
//            else
//                if (log.IsErrorEnabled)
//                    log.Error("unhandeld global error", ex);

        }

        void Session_Start(object sender, EventArgs e)
        {
            //Remove old session settings search result blocks
            HttpCookieCollection c = HttpContext.Current.Request.Cookies;
            for (int i = 0; i < c.Count; i++)
            {
                if (c[i].Name.IndexOf("shsb") == 0)
                {
                    HttpContext.Current.Request.Cookies.Remove(c[i].Name);
                    i--;
                }
            }
            // Code that runs when a new session is started

        }

        void Session_End(object sender, EventArgs e)
        {
            // Code that runs when a session ends. 
            // Note: The Session_End event is raised only when the sessionstate mode
            // is set to InProc in the Web.config file. If session mode is set to StateServer 
            // or SQLServer, the event is not raised.

        }


    }
}